import { NotFound, NotFoundItem, Repeatedly, Success } from "../../code/http-exception";
import auth from "../../middlewares/auth"
import { sequelize } from "../../sql/db";
import CommType from "../../sql/module/customize/commType";
import Community from "../../sql/module/customize/community";
import CommTypeItem from "../../sql/module/customize/commTypeItem";
import { InfoValidator, ListValidator } from "../../validators/public";
import Customize from "../../sql/module/customize/index";
import { Op } from "sequelize";
import { AddCustomizeValidator } from "../../validators/customize";
import Memo from "../../sql/module/customize/index/memo";
import GroupMessage from "../../sql/module/group/groupMessage";
import User from "../../sql/module/user/user";
import Group from "../../sql/module/group/group";
import { CUSTOMIZESTATE } from "../../lib/enum";
import ImgCustomize from "../../sql/module/customize/index/img_customize";

CommType.hasMany(CommTypeItem)
CommTypeItem.belongsTo(CommType)
Community.hasMany(CommType)
CommType.belongsTo(Community)
User.hasOne(Customize)
Customize.belongsTo(User)
Community.hasMany(Customize)
Customize.belongsTo(Community)
Customize.hasMany(Memo)
Memo.belongsTo(Customize)
Customize.hasMany(ImgCustomize, { as: 'imgs' })
ImgCustomize.belongsTo(Customize)
GroupMessage.hasOne(Memo)
Memo.belongsTo(GroupMessage)

const router: Api = new Map()
/**
 * 添加小区
 * @param id string 小区名
 * @param latitude string 经度
 * @param longitude string 纬度
 */
router.set('/addCommunity', [auth('community'), async (ctx) => {
    const v = await new InfoValidator().validate(ctx)
    const UserId = ctx.auth.id
    await sequelize.sync()
    const name = v.get('body.id')
    const latitude = v.get('body.latitude')
    const longitude = v.get('body.longitude')
    const comm = await Community.create({ name, latitude, longitude, UserId })
    throw new Success(comm)
}])
/**
 * 删除小区
 * @param id string 小区ID
 */
router.set('/deleteCommunity', [auth('community'), async (ctx) => {
    const v = await new InfoValidator().validate(ctx)
    const UserId = ctx.auth.id
    await sequelize.sync()
    const id = v.get('query.id')
    const res = await Community.destroy({
        where: {
            UserId,
            id
        }
    })
    if (res === 0) throw new NotFoundItem('小区不可删除')
    throw new Success()
}])
//开始会话
router.set('/createGroupCustomize', [auth(['customizeSelf', 'scheduled']), async (ctx, next) => {
    const v = await new InfoValidator().validate(ctx)
    const CustomizeId = v.get('query.id')
    await Customize.update({
        state: CUSTOMIZESTATE.ONC2C
    }, {
        where: {
            id: CustomizeId, state: CUSTOMIZESTATE.UN_CONFIRM
        }
    })
    const group = await Group.findAll({ where: { groupName: 'Cus' + CustomizeId } })
    if (group.length) { throw new Success() }
    const customize = await Customize.findOne({ where: { id: CustomizeId } })
    if (!customize) { throw new NotFoundItem('定制订单未发现') }
    const { UserId, toUserId } = customize.dataValues
    const message = await GroupMessage.create({
        UserId: customize.dataValues.UserId, groupName: 'Cus' + CustomizeId, msg: '定制会话开始', type: 'text'
    })
    const Users = [UserId, toUserId].map(item => ({ UserId: item, groupName: 'Cus' + CustomizeId, lastMessage: message.dataValues.id, type: 'Cus' }))
    await Group.bulkCreate(Users)
    throw new Success('Cus' + CustomizeId)
}])
/**
 * 小区列表
 *  @returns { list, total }
 */
router.set('/communityList', [auth('community'), async (ctx) => {
    await sequelize.sync()
    const { rows, count } = await Community.findAndCountAll()
    throw new Success({ list: rows, total: count })
}])
/**
 * 房型列表
 * @param id string 小区ID
 * @returns { list, total }
 */
router.set('/commTypeList', [auth('community'), async (ctx) => {
    const v = await new InfoValidator().validate(ctx)
    await sequelize.sync()
    const CommunityId = v.get('body.id')
    const { rows, count } = await CommType.findAndCountAll({
        where: {
            CommunityId
        }, include: CommTypeItem
    })
    throw new Success({ list: rows, total: count })
}])
/**
 * 房型详情列表
 * @param id string 房型ID
 */
router.set('/commTypeItemList', [auth('community'), async (ctx) => {
    const v = await new InfoValidator().validate(ctx)
    await sequelize.sync()
    const CommTypeId = v.get('query.id')
    const items = await CommTypeItem.findAll({
        where: {
            CommTypeId
        }
    })
    throw new Success(items)
}])
/**
 * 添加房型
 * @param id string 小区ID
 * @param CommTypeItems string[] 详情列表
 */
router.set('/addCommType', [auth('community'), async (ctx) => {
    const v = await new InfoValidator().validate(ctx)
    await sequelize.sync()
    const id = v.get('body.id')
    const CommTypeItems = v.get('body.CommTypeItems')
    const commtype = await CommType.create({ CommunityId: id })
    await CommTypeItem.bulkCreate(CommTypeItems.map((item: any) => ({ CommTypeId: commtype.dataValues.id, ...item })))
    throw new Success()
}])
/**
 * 修改房型名称
 * @param id string 房型ID
 * @param name string[] 名称
 */
router.set('/addCommTypeName', [auth('community'), async (ctx) => {
    const v = await new InfoValidator().validate(ctx)
    await sequelize.sync()
    const id = v.get('body.id')
    const name = v.get('body.name')
    const commtype = await CommType.update({ name }, { where: { id } })
    throw new Success()
}])
/**
 * 修改房型详情
 * @param id string 房型ID
 * @param CommTypeItems string[] 详情列表
 */
router.set('/changeCommType', [auth('community'), async (ctx) => {
    const v = await new InfoValidator().validate(ctx)
    await sequelize.sync()
    const id = v.get('query.id')
    const CommTypeItems = v.get('body.CommTypeItems')
    const commtype = await CommType.findOne({ where: { id } })
    if (!commtype) { throw new NotFound() }
    await CommTypeItem.destroy({ where: { CommTypeId: commtype.dataValues.id } })
    await CommTypeItem.bulkCreate(CommTypeItems.map((item: any) => ({ CommTypeId: commtype.dataValues.id, ...item })))
    throw new Success()
}])
/**
 * 房型详情
 * @param id string 房型ID
 */
router.set('/commTypeInfo', [auth(['customizeSelf', 'community']), async (ctx) => {
    const v = await new InfoValidator().validate(ctx)
    await sequelize.sync()
    const id = v.get('query.id')
    const commtype = await CommType.findOne({
        where: { id },
        include: CommTypeItem
    })
    if (!commtype) { throw new NotFound() }
    throw new Success(commtype)
}])
/**
 * 删除房型
 * @param id string 房型ID
 */
router.set('/deleteCommType', [auth('community'), async (ctx) => {
    const v = await new InfoValidator().validate(ctx)
    await sequelize.sync()
    const id = v.get('query.id')
    const commtype = await CommType.findOne({ where: { id } })
    if (!commtype) { throw new NotFound() }
    await commtype.destroy()
    await CommTypeItem.destroy({ where: { CommTypeId: commtype.dataValues.id } })
    throw new Success()
}])
/**
 * 预定列表
 * @returns { list, total }
 */
router.set('/scheduledList', [auth('scheduled'), async (ctx) => {
    const v = await new ListValidator().validate(ctx)
    const UserId = ctx.auth.id
    await sequelize.sync()
    const limit = v.get('query.limit')
    const page_index = v.get('query.page_index')
    const { rows, count } = await Customize.findAndCountAll({
        where: {
            state: [CUSTOMIZESTATE.CONFIRM, CUSTOMIZESTATE.UN_CONFIRM, CUSTOMIZESTATE.ONC2C],
            toUserId: UserId
        },
        distinct: true,
        include: [Community, { model: User, attributes: ['nickname'] }],
        limit: limit * 1,
        offset: (page_index - 1) * limit,
        order: [['state', 'DESC']]
    })
    throw new Success({ list: rows, total: count })
}])
/**
 * 案例列表
 * @returns { list, total }
 */
router.set('/customizeList', [auth(['customizeSelf', 'customizeList']), async (ctx) => {
    const v = await new ListValidator().validate(ctx)
    await sequelize.sync()
    const UserId = v.get('body.UserId') || ctx.auth.id
    const limit = v.get('query.limit')
    const page_index = v.get('query.page_index')
    const { rows, count } = await Customize.findAndCountAll({
        where: {
            state: [CUSTOMIZESTATE.FINISH, CUSTOMIZESTATE.HIDE],
            toUserId: UserId
        },
        distinct: true,
        include: [Community, { model: User, attributes: ['nickname'] }, { model: ImgCustomize, as: 'imgs' }],
        limit: limit * 1,
        offset: (page_index - 1) * limit
    })
    throw new Success({ list: rows, total: count })
}])
/**
 * 案例列表
 * @returns { list, total }
 */
router.set('/customizePublicList', [auth('public'), async (ctx) => {
    const v = await new ListValidator().validate(ctx)
    await sequelize.sync()
    const UserId = v.get('body.UserId') || ctx.auth.id
    const limit = v.get('query.limit')
    const page_index = v.get('query.page_index')
    const { rows, count } = await Customize.findAndCountAll({
        where: {
            state: CUSTOMIZESTATE.FINISH,
            toUserId: UserId
        },
        distinct: true,
        include: [Community, { model: User, attributes: ['nickname'] }, { model: ImgCustomize, as: 'imgs' }],
        limit: limit * 1,
        offset: (page_index - 1) * limit
    })
    throw new Success({ list: rows, total: count })
}])
/**
 * 隐藏案例
 */
router.set('/hideCustomize', [auth('customizeList'), async (ctx) => {
    const v = await new InfoValidator().validate(ctx)
    const id = v.get('query.id')
    const customize = await Customize.findOne({
        where: {
            id
        }
    })
    if (!customize) { throw new NotFoundItem() }
    const state = customize.dataValues.state
    if (state === CUSTOMIZESTATE.FINISH) {
        await customize.update({
            state: CUSTOMIZESTATE.HIDE
        })
        throw new Success('hide')
    } else if (state === CUSTOMIZESTATE.HIDE) {
        await customize.update({
            state: CUSTOMIZESTATE.FINISH
        })
        throw new Success('show')
    } else {
        throw new NotFoundItem('订单状态有误')
    }
}])
/**
 * 添加定制订单
 */
router.set('/addCustomize', [auth('public'), async (ctx) => {
    const v = await new AddCustomizeValidator().validate(ctx)
    await sequelize.sync()
    const UserId = ctx.auth.id
    const phone = v.get('body.phone')
    const community = v.get('body.community')
    const toUserId = v.get('body.toUserId')
    await Customize.create({
        UserId, toUserId, community, phone
    })
    throw new Success()
}])

/**
 * 取消定制订单
 */
router.set('/cancalCustomize', [auth('public'), async (ctx) => {
    const v = await new InfoValidator().validate(ctx)
    const id = v.get('query.id')
    const UserId = ctx.auth.id
    await sequelize.sync()
    await Customize.update({
        state: 0
    }, {
        where: {
            id, UserId,
            state: [CUSTOMIZESTATE.UN_CONFIRM, CUSTOMIZESTATE.ONC2C]
        }
    })
    throw new Success()
}])

/**
 * 定制详情
 */
router.set('/customizeInfo', [auth(['customizeSelf', 'addCustomize']), async (ctx) => {
    const v = await new InfoValidator().validate(ctx)
    await sequelize.sync()
    const id = v.get('query.id')
    const res = await Customize.findOne({
        where: {
            id
        }, include: { model: User, attributes: ['nickname'] }
    })
    throw new Success(res)
}])
/**
 * 添加记录
 */
router.set('/addMemo', [auth('communityGroup'), async (ctx) => {
    const v = await new InfoValidator().validate(ctx)
    await sequelize.sync()
    const GroupMessageId = v.get('body.id')
    const CustomizeId = v.get('body.CustomizeId')
    const memo = await Memo.findOne({
        where: { GroupMessageId, CustomizeId }
    })
    if (memo) throw new Repeatedly()
    await Memo.create({
        GroupMessageId, CustomizeId
    })
    throw new Success()
}])
/**
 * 删除记录
 */
router.set('/deleteMemo', [auth('communityGroup'), async (ctx) => {
    const v = await new InfoValidator().validate(ctx)
    await sequelize.sync()
    const id = v.get('body.id')
    const memo = await Memo.findOne({
        where: { id }
    })
    if (!memo) { throw new NotFoundItem() }
    await memo.update({ isDelete: true })
    throw new Success()
}])
/**
 * 获取记录列表
 */
router.set('/memoList', [auth(['customizeSelf', 'memo']), async (ctx) => {
    const v = await new InfoValidator().validate(ctx)
    await sequelize.sync()
    const CustomizeId = v.get('query.id')
    const memo = await Memo.findAll({
        where: { CustomizeId },
        include: {
            model: GroupMessage,
            include: {
                //@ts-ignore
                model: User,
                attributes: ['nickname']
            }
        }
    })
    throw new Success(memo)
}])
//群组列表
router.set('/groupList', [auth('communityGroup'), async (ctx, next) => {
    const v = await new ListValidator().validate(ctx)
    const UserId = ctx.auth.id
    const limit = v.get('query.limit')
    const page_index = v.get('query.page_index')

    const { rows, count } = await Group.findAndCountAll({
        where: { UserId, type: 'Cus', deleted: false },
        include: [{
            model: GroupMessage, as: 'LastMessage',
            //@ts-ignore
            include: { model: User, attributes: ['nickname', 'avatar', 'fullUrl'] },
        }],
        distinct: true,
        limit: limit * 1,
        offset: (page_index - 1) * limit,
        order: [['updatedAt', 'DESC']]
    })
    throw new Success({ list: rows, total: count })
}])
/**
 * 个人定制列表
 */
router.set('/customizeSelf', [auth('customizeSelf'), async (ctx) => {
    const v = await new ListValidator().validate(ctx)
    await sequelize.sync()
    const UserId = ctx.auth.id
    const limit = v.get('query.limit')
    const page_index = v.get('query.page_index')
    const { rows, count } = await Customize.findAndCountAll({
        where: {
            UserId,
            state: { [Op.not]: CUSTOMIZESTATE.CNACAL }
        },
        distinct: true,
        limit: limit * 1,
        offset: (page_index - 1) * limit
    })
    throw new Success({ list: rows, total: count })
}])
/**
 * 确认订单
 */
router.set('/confirm', [auth('confirmCustomize'), async (ctx, next) => {
    const v = await new InfoValidator().validate(ctx)
    const CustomizeId = v.get('query.id')
    const UserId = ctx.auth.id
    await Customize.update({
        state: CUSTOMIZESTATE.CONFIRM
    }, {
        where: {
            id: CustomizeId,
            state: CUSTOMIZESTATE.ONC2C,
            toUserId: UserId
        }
    })
    throw new Success()
}])
/**
 * 完成订单
 */
router.set('/finish', [auth('public'), async (ctx) => {
    const v = await new InfoValidator().validate(ctx)
    const id = v.get('query.id')
    const imgs = v.get('body.imgs')
    await Customize.update({
        state: CUSTOMIZESTATE.FINISH
    }, {
        where: {
            id,
            state: CUSTOMIZESTATE.CONFIRM
        }
    })
    if (imgs) {
        const count = await ImgCustomize.count({ where: { CustomizeId: id } })
        const new_imgs = imgs.slice(count, imgs.length)
        await ImgCustomize.bulkCreate(new_imgs.map((item: any) => ({ CustomizeId: id, url: item })))
    }
    throw new Success()
}])
/**
 * 获取定制图片
 */
router.set('/getImgs', [auth('public'), async (ctx) => {
    const v = await new InfoValidator().validate(ctx)
    const id = v.get('query.id')
    const customize = await Customize.findOne({ where: { id }, attributes: ['toUserId'] })
    if (!customize) { throw new NotFoundItem('案例不存在') }
    const user = await User.findOne({ where: { id: customize?.dataValues.toUserId }, attributes: ['id', 'nickname', 'avatar', 'fullUrl'] })
    if (!user) { throw new NotFoundItem('用户不存在') }
    const imgs = await ImgCustomize.findAll({ where: { CustomizeId: id } })
    throw new Success({ user, imgs })
}])
export { router }